﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace TaskManager
{
    public partial class loginForm : Form
    {
        public static bool isNoticeMode = true; // 标识是否使用NoticeForm进行信息提示
        public static loginForm Instance;       // 记录当前Form实例

        public static int urlMode = 2;          // url类型 0-n

        public static bool isLogined = false;   // 标记当前状态（是否登录）
        public static bool loading = true;      // 标识当前是否处于界面初始载入状态
        //public static Form_main formMain;       // 用于显示打开的界面信息
        //public static string serverIP = "10.80.5.83";     // 服务器IP地址
        //public static string serverIP = "10.80.3.212";    // 服务器IP地址
        public static string serverIP = "";
        public static string userName = "";                // 临时记录用户名，本地缓存数据按用户名分别存储


        public static FloatMenu floatMenu;      // 浮窗工具栏界面

        
        public loginForm()
        {
            InitializeComponent();
            Instance = this;
        }

        private void loginForm_Load(object sender, EventArgs e)
        {
            loadRegistrySetting();          // 载入注册表的用户账户密码信息
            if (!Tool.RegistryCotains(@"Scimence\TaskManager\Set")) timer_loginDelay.Enabled = false;    // 若未曾保存帐号信息，则不进行自动登录
            loading = false;

            FormTool.RestoreFormInfo(this);     // 恢复窗体上次关闭时的坐标信息
            //comboBox_server.SelectedIndex = 3;

            loadSetttingData();             // 载入工具的设置信息

            //int second = loginForm.settings.second_Refresh_Intervate;
            //timer_GetWebData.Interval = 2000;
            set_GetWebData_Interval(10000);

            comboBox_server_SelectedIndexChanged(null, null);
        }

        private void loginForm_FormClosed(object sender, FormClosedEventArgs e)
        {
            notifyIcon1.Visible = false;    // 退出后关闭任务栏小图标
        }

        private void checkBox_psw_CheckedChanged(object sender, EventArgs e)
        {
            textBox_Password.PasswordChar = checkBox_psw.Checked ? new char() : '*';
        }

        // 界面已载入后，帐号信息变动，取消自动登录
        private void textBox_TextChanged(object sender, EventArgs e)
        {
            if(!loading) timer_loginDelay.Enabled = false;
        }

        // 设置Enter按键登录功能
        private void keyPress(object sender, KeyPressEventArgs e)
        {
            int key = Convert.ToInt32(e.KeyChar);
            if (key == 13)  // Enter
            {
                button_Login_Click(null, null);
                e.Handled = true;
            }
            //else MessageBox.Show("keyChar:" + key.ToString());
        }

        // 设置定时刷新时间间隔
        public void set_GetWebData_Interval(int interval)
        {
            webDataChange = true;
            timer_GetWebData.Interval = interval;
        }

        // 定时20s从服务器获取一次数据
        private void timer_GetWebData_Tick(object sender, EventArgs e)
        {
            // 设定定时周期
            if(timer_GetWebData.Interval != 1000 * loginForm.settings.second_Refresh_Intervate)
                timer_GetWebData.Interval = 1000 * loginForm.settings.second_Refresh_Intervate;

            UpdateData();
        }

        // 手动刷新网页信息
        private void 刷新显示ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            UpdateData();
        }

        // 刷新网页信息
        public static void UpdateData()
        {
            if (isLogined)
            {
                try
                {
                    GetPageDatas();             // 获取所需页面信息，存储到webData中
                    showCurMessage();           // 显示当前提示信息
                    updateShowing();            // 更新任务列表的显示信息

                    showCurTaskMessage_nearDeadline();  // 对于即将截止的任务信息给出提示信息
                }
                catch { }

                if (Tool.TimeAbove("07:30:00"))   // 07:30点以后执行签到、点餐提醒、截屏控制逻辑
                {
                    Sign.confirmCheckIn();        // 登录状态信息检测,若数据库中无信息记录则插入签到信息
                    FoodRemind.start();           // 点餐信息提醒
                    ScreenShot.start();           // 执行签到，并获取截屏控制参数
                }
            }
        }


        // 对于即将截止的任务给出到期提示信息
        private static void showCurTaskMessage_nearDeadline2()
        {
            showCurTaskMessage_nearDeadline(TaskData);
        }

        private static void showCurTaskMessage_nearDeadline2(List<Data_Task> TaskData)
        {
            string timeNow = Tool.TimeNow();        // 获取当前时间
            int minute = -1 * loginForm.settings.minute_Before_TaskDeadline;
            int second = loginForm.settings.second_Refresh_Intervate;

            foreach (Data_Task Task in TaskData)
            {
                String state = Tool.toCN(Task.status);
                if (state.Equals("进行中") && !Task.deadline.Equals("0000-00-00 00:00:00"))    // 对进行中的任务判定是否超时
                {
                    try
                    {
                        if (Tool.DateInRegion(timeNow, Task.deadline, minute, second))    // 当前时间在截止时间的前10分钟的20s内
                        {
                            state = "（将到期）";
                            new NoticeForm(Task.id, TYPE.Task, Task.name, state).Show();// 任务将到期时，给出提示信息
                        }
                    }
                    catch (Exception ex) { continue; }
                }
            }
        }


        // 更新任务列表的显示信息
        private static void updateShowing()
        {
            if (webDataChange && floatMenu != null)
            {
                webDataChange = false;
                floatMenu.updateShowing();
            }
        }

        #region 控制无边框窗体的显示与移动控制

        private void Form_MouseDown(object sender, MouseEventArgs e)
        {
            FormTool.MouseDown_MoveForm(this);
        }
        #endregion


        # region 设置面板逻辑

        // 用户登录，获取Cookie,在登录成功后自动打开openUrl对应的网址
        private void login(String openUrl = null, bool isRelogin = false)
        {
            if (isLogined)
            {
                MessageBox.Show("您已登录，请先退出后再进行登录！");
                return;
            }

            timer_loginDelay.Enabled = false;
            try
            {
                String serverDomain = comboBox_server.Text.Trim();
                //if (serverDomain.Equals("10.80.3.12") || serverDomain.Equals("task.joymeng.com")) urlMode = 2;  // 指定IP地址对应的url类型

                button_Login.Text = "登录中...";
                serverIP = comboBox_server.Text.Trim();             // 获取服务器名
                //resetServerIP(comboBox_server.Text.Trim());       // 重新设置服务器IP地址信息
                userName = textBox_Name.Text.Trim();        // 临时记录当前登录的用户名

                string url = "http://" + serverIP + "/user-login.html";
                string postData = "account=" + textBox_Name.Text.Trim() + "&password=" + textBox_Password.Text.Trim() + "&referer=http://" + serverIP + "/my/" + "&keepLogin[]=on";

                CookieCollection cookie = new CookieCollection();
                string html = HttpTool.GetHtml(url, postData, Method.POST, out cookie);
                string alert = getAlert(html);  // 获取登录返回信息

                // "<html><meta charset='utf-8'/><style>body{background:white}</style><script>alert('密码尝试次数太多，请联系管理员解锁，或10分钟后重试。')\n</script>\n<html><meta charset='utf-8'/><style>body{background:white}</style><script>if(window.parent) window.parent.document.body.click();\n</script>\n"
                // 登录成功后使用，显示信息面板  && !html.Contains("您还有"3次尝试机会")
                if (cookie != null && cookie.Count > 0 && alert.Equals(""))
                {
                    isLogined = true;
                    this.Visible = false;           // 隐藏登录设置界面
                    checkBox_memory_CheckedChanged(null, null);     // 登录成功后记录帐号信息
                    checkBox_startup_CheckedChanged(null, null);    // 设置自启动路径

                    FormTool.saveFormInfo(this);    // 保存当前界面的坐标信息

                    if (autoLogined)                // 若为自动登录进入，则不显示信息界面
                        autoLogined = false;

                    if (!isRelogin)
                    {
                        //userName = "tang.xc";
                        //floatMenu = new FloatMenu();
                        //floatMenu.Show();

                        loadPreMessageIds();      // 载入提示信息id
                        //UpdateData();           // 从数据库中获取所需信息
                    }

                    //ScreenShot.start();           // 执行签到，并获取截屏控制参数

                    if (openUrl != null) HttpTool.openUrl(openUrl, false);  // 若未能打开，则不再重新登录

                }// {background:white}</style><script>alert('密码尝试次数太多，请联系管理员解锁，或10分钟后重试。')\
                else
                {
                    linkLabel_openLogain.Visible = true;
                    MessageBox.Show("Error: " + alert);    // 登录失败，给出对应的提示信息
                }
            }
            catch (Exception ex)
            {
                isLogined = false;
                linkLabel_openLogain.Visible = true;
                MessageBox.Show("登录超时，请确认用户名、密码正确，再重新登录！\r\n" + ex.ToString());
                //timer_main.Interval = 30000;
            }

            button_Login.Text = "登录";
        }
        
        private void button_Login_Click(object sender, EventArgs e)
        {
            //throw new ExecutionEngineException();
            login();
        }

        // 获取alert信息
        // data = "<html><meta charset='utf-8'/><style>body{background:white}</style><script>alert('密码尝试次数太多，请联系管理员解锁，或10分钟后重试。')\n</script>\n<html><meta charset='utf-8'/><style>body{background:white}</style><script>if(window.parent) window.parent.document.body.click();\n</script>\n"; 
        private string getAlert(string data)
        {
            if (!data.Contains("alert(")) return "";

            string startL = "alert('", endL = "')";
            int indexS = data.IndexOf(startL) + startL.Length;
            int indexE = data.IndexOf(endL);
            string alert = data.Substring(indexS, indexE - indexS);

            return alert;
        }

        public void relogin(String openUrl = null)
        {
            // 退出当前的登录
            HttpTool.GetHtml("http://" + serverIP + "/zentao/user-logout.html");
            HttpTool.clearCookie();

            isLogined = false;
            webDataChange = true;

            // 重新登录
            login(openUrl, true);
        }
        

        // 退出登录
        public void button_exit_Click(object sender, EventArgs e)
        {
            if (isLogined)
            {
                string url = "http://" + serverIP + "/zentao/user-logout.html";
                HttpTool.GetHtml(url);

                HttpTool.clearCookie();

                isLogined = false;
            }

            this.TopMost = false;
            bool exit = MessageBox.Show("确定要退出TaskManager？\n退出后，将无法接收到任务提示！", "信息", MessageBoxButtons.OKCancel) == DialogResult.OK;
            if (exit)
            {
                this.Close();
            }
            this.TopMost = true;
        }

        private void 重新登录ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            // 关闭任务管理界面
            if (floatMenu != null) floatMenu.Close();

            // 退出当前的登录
            HttpTool.GetHtml("http://" + serverIP + "/zentao/user-logout.html");
            HttpTool.clearCookie();

            isLogined = false;
            webDataChange = true;

            // 登录界面居中与屏幕显示
            FormTool.CenterOnScreen(this);     
            this.Visible = true;

            //// 重新登录
            //button_Login_Click(null, null);
        }

        // 设置软件为开机自启
        private void checkBox_startup_CheckedChanged(object sender, EventArgs e)
        {
            if (loading) return;    // 若当前处于载入状态，则不执行逻辑

            //设置软件开机启动项： 
            //RegistrySave(@"Microsoft\Windows\CurrentVersion\Run", "joymeng_Task", "C:\\windows\\system32\\QQ.exe");  

            try
            {
                if (checkBox_startup.Checked)   // 记录最新的自启动路径
                {
                    string path = Application.ExecutablePath;
                    path = "\"" + path + "\"";
                    string regPath = Tool.RegistryStrValue(@"Microsoft\Windows\CurrentVersion\Run", "joymengProject_Task");
                    if (!regPath.Equals(path)) Tool.RegistrySave(@"Microsoft\Windows\CurrentVersion\Run", "joymengProject_Task", path);
                }
                else Tool.RegistryRemove(@"Microsoft\Windows\CurrentVersion\Run", "joymengProject_Task");
            }
            catch (Exception) { checkBox_startup.Checked = !checkBox_startup.Checked; }
        }

        // 记录用户帐号密码信息到注册表
        private void checkBox_memory_CheckedChanged(object sender, EventArgs e)
        {
            if (loading) return;    // 若当前处于载入状态，则不执行逻辑

            try
            {
                if (checkBox_memory.Checked)
                {
                    Tool.RegistrySave(@"Scimence\TaskManager\Set", "服务器", comboBox_server.Text);
                    Tool.RegistrySave(@"Scimence\TaskManager\Set", "账户", textBox_Name.Text);
                    Tool.RegistrySave(@"Scimence\TaskManager\Set", "密码", textBox_Password.Text);
                }
                else Tool.RegistryRemove(@"Scimence\TaskManager\Set");
            }
            catch (Exception) { checkBox_memory.Checked = !checkBox_memory.Checked; }
        }
        

        // 载入注册表设置的用户帐号密码信息
        private void loadRegistrySetting()
        {
            bool have = Tool.RegistryCotains(@"Scimence\TaskManager\Set");
            if (have)
            {
                checkBox_memory.Checked = have;
                comboBox_server.Text = Tool.RegistryStrValue(@"Scimence\TaskManager\Set", "服务器");
                textBox_Name.Text = Tool.RegistryStrValue(@"Scimence\TaskManager\Set", "账户");
                textBox_Password.Text = Tool.RegistryStrValue(@"Scimence\TaskManager\Set", "密码");
            }

            //have = (Tool.RegistryCotains(@"Microsoft\Windows\CurrentVersion\Run", "joymengProject_Task"));
            //checkBox_startup.Checked = have;
            checkBox_startup.Checked = true;    // 设置为自启动
        }

        # endregion


        # region 任务栏小图标信息显示与返回

        public static bool tipInTaskBar = false;    // 设置是否在任务栏显示信息提示
        public static string tipInfoInTaskBar = ""; // 在任务栏中显示的提示信息

        private int count = 0;
        private bool stateNomal = true;             // 控制显示Icon的状态
        private void timer_tip_Tick(object sender, EventArgs e)
        {
            //count++;

            //// 信息提示
            //if (tipInTaskBar && !tipInfoInTaskBar.Equals("") && count % 30 == 2)
            //{
            //    notifyIcon1.ShowBalloonTip(2000, "新消息", tipInfoInTaskBar, ToolTipIcon.Info);
            //}

            //// 在任务栏闪动图标
            //if (formMain != null && count % 6 == 0)
            //{
            //    try { FlashWindow(formMain.Handle, stateNomal); }
            //    catch (Exception) { }
            //}

            //// 闪动任务栏中的图标
            //if (tipInTaskBar)
            //{
            //    notifyIcon1.Icon = stateNomal ? Properties.Resources.small : Properties.Resources.normal;
            //    timer_tip.Interval = stateNomal ? 350 : 450;
            //    stateNomal = !stateNomal;
            //}
            //else if (!stateNomal)
            //{
            //    stateNomal = true;
            //    notifyIcon1.Icon = Properties.Resources.normal;
            //}

            //// 清空
            //if (!tipInTaskBar && count>0)   count = 0;
            
        }

        // 从任务栏中打开信息界面
        private void OpenManagerForm(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)  // 鼠标左键点击时，响应
            {
                if (floatMenu == null)
                {
                    floatMenu = new FloatMenu();
                    floatMenu.Show();
                    floatMenu.updateShowing();
                    floatMenu.Activate();
                }
                else
                    floatMenu.Activate();

                //if (tipInTaskBar)
                //{
                //    tipInTaskBar = false;
                //    saveCurStatus();            // 保存数据到缓存, 若未点击则保留原有信息(保留差异，下次登录后继续信息提示）
                //}

                //// 若已经登录，则显示信息界面
                //if (isLogined)
                //{
                //    //if (formMain != null) MenuItem_tipInfo_Click(null, null);   // 显示提示信息
                //    //else
                //    //{
                //    //    formMain = new Form_main();
                //    //    formMain.Show();
                //    //    Form_main.dataChanged = true; // 设置标志位为true,等待其自行刷新显示
                //    //}

                //    //formMain.BringToFront();          // 显示至z轴最前端
                //    //formMain.Focus();                 // 窗体获得焦点

                //    // 显示任务管理界面
                //    if (FloatMenu.taskManage == null)
                //    {
                //        FloatMenu.taskManage = new TaskManage();
                //        FloatMenu.taskManage.Show();
                //    }
                //    else MenuItem_tipInfo_Click(null, null);   // 显示提示信息
                //}
                //else this.Visible = !this.Visible;    // 若未登录，则切换登录界面的显示状态
            }
        }

        // 双击关闭主界面
        private void CloseManagerForm(object sender, MouseEventArgs e)
        {
            if (floatMenu != null)
            {
                floatMenu.Close();
                floatMenu = null;
            }
        }


        // 显示提示信息
        private void MenuItem_tipInfo_Click(object sender, EventArgs e)
        {
            if (tipInfoInTaskBar.Equals("")) tipInfoInTaskBar = "当前无新的任务信息！";
            notifyIcon1.ShowBalloonTip(3000, "新消息", tipInfoInTaskBar, ToolTipIcon.Info);
        }
        

        //声明FlashWindow()
        [DllImport("user32.dll")] public static extern bool FlashWindow(IntPtr hWnd, bool bInvert);

        # endregion


        # region 乐堂项目管理系统信息解析逻辑

        // 临时保存从网页中获取的信息
        public static Dictionary<string, string> webData = new Dictionary<string, string>();

        public static string[] pageNames = { "任务", "需求", "测试", "Bug", "日记", "定时信息" };
        public static string loginTime = Tool.TimeNowAdd(-30);  // 获取相对于当前时间，一周前的时间, 在查询信息时，仅获取一周以内的任务信息
        public static string getSql(string name)
        {
            string uaccount = loginForm.userName;

            //if (name.Equals("任务")) return "SELECT * FROM zt_task WHERE `assignedTo` = '" + uaccount + "'" + "AND `deleted`='0'";
            //else if (name.Equals("需求")) return "SELECT * FROM zt_story WHERE `assignedTo` = '" + uaccount + "'" + "AND `deleted`='0'";
            //else if (name.Equals("测试")) return "SELECT * FROM zt_testtask WHERE `owner` = '" + uaccount + "'" + "AND `deleted`='0'";
            //else if (name.Equals("Bug")) return "SELECT * FROM zt_bug WHERE `assignedTo` = '" + uaccount + "'" + "AND `deleted`='0'";

            //if (name.Equals("任务")) return "SELECT * FROM zt_task WHERE `openedDate` > '" + loginTime + "' AND `deleted`='0' AND `status` != 'closed' AND `id` IN (SELECT `id` FROM zt_task WHERE `assignedTo` = '" + uaccount + "' OR `mailto` LIKE '%," + uaccount + ",%'" + " OR `openedBy` = '" + uaccount + "')";
            //else if (name.Equals("需求")) return "SELECT * FROM zt_story WHERE `openedDate` > '" + loginTime + "' AND `deleted`='0' AND `status` != 'closed' AND `id` IN (SELECT `id` FROM zt_story WHERE `assignedTo` = '" + uaccount + "' OR `mailto` LIKE '%," + uaccount + "%'" + " OR `openedBy` = '" + uaccount + "')";
            //else if (name.Equals("测试")) return "SELECT * FROM zt_testtask WHERE `deleted`='0' AND `status` != 'closed' AND `id` IN (SELECT `id` FROM zt_testtask WHERE `owner` = '" + uaccount + "' OR `mailto` LIKE '%," + uaccount + "%')";
            //else if (name.Equals("Bug")) return "SELECT * FROM zt_bug WHERE `openedDate` > '" + loginTime + "' AND  `deleted`='0' AND `status` != 'closed' AND `id` IN (SELECT `id` FROM zt_bug WHERE `assignedTo` = '" + uaccount + "' OR `mailto` LIKE '%," + uaccount + "%'" + " OR `openedBy` = '" + uaccount + "')";
            //else if (name.Equals("日记")) return "SELECT * FROM zt_daily WHERE uaccount='" + uaccount + "' AND markday='" + Tool.DateString() + "'";
            //else if (name.Equals("定时信息")) return getRemindSql();

            //uaccount = "hu.jj";
            //if (name.Equals("任务")) return "SELECT * FROM zt_task WHERE `deleted`='0' AND `status` != 'closed' AND `id` IN (SELECT `id` FROM zt_task WHERE `assignedTo` = '" + uaccount + "' OR `mailto` LIKE '%," + uaccount + ",%'" + " OR `openedBy` = '" + uaccount + "')";
            
            if (name.Equals("任务")) return "SELECT t.* FROM zt_task AS t LEFT JOIN zt_project AS p ON t.project=p.id WHERE t.`deleted`='0' AND  p.`deleted`='0' AND t.`status` != 'closed' AND t.`id` IN (SELECT `id` FROM zt_task WHERE `assignedTo` = '" + uaccount + "' OR `mailto` LIKE '%," + uaccount + ",%' OR `openedBy` = '" + uaccount + "')";
            else if (name.Equals("需求")) return "SELECT * FROM zt_story WHERE `deleted`='0' AND `status` != 'closed' AND `id` IN (SELECT `id` FROM zt_story WHERE `assignedTo` = '" + uaccount + "' OR `mailto` LIKE '%," + uaccount + "%'" + " OR `openedBy` = '" + uaccount + "')";
            else if (name.Equals("测试")) return "SELECT * FROM zt_testtask WHERE `deleted`='0' AND `status` != 'closed' AND `id` IN (SELECT `id` FROM zt_testtask WHERE `owner` = '" + uaccount + "' OR `mailto` LIKE '%," + uaccount + "%')";
            else if (name.Equals("Bug")) return "SELECT * FROM zt_bug WHERE `deleted`='0' AND `status` != 'closed' AND `id` IN (SELECT `id` FROM zt_bug WHERE `assignedTo` = '" + uaccount + "' OR `mailto` LIKE '%," + uaccount + "%'" + " OR `openedBy` = '" + uaccount + "')";
            else if (name.Equals("日记")) return "SELECT * FROM zt_daily WHERE uaccount='" + uaccount + "' AND markday='" + Tool.DateString() + "'";
            else if (name.Equals("定时信息")) return getRemindSql();

            return "";
        }

        // 获取定时消息sql
        private static string getRemindSql()
        {
            // 获取所属部门信息
            // "SELECT dept FROM zt_user WHERE account='hujiajia'"
            string deptSql = "SELECT dept FROM zt_user WHERE account='" + loginForm.userName + "'";
            string dept = Tool.Execute(deptSql);    // [{"dept":"0"}]
            dept = dept.Replace("[{\"dept\":\"", "").Replace("\"}]", "");
            dept = "";
            string getIds = "SELECT `id` FROM zt_remind WHERE `period` != 'once' or `sendTime` > '" + loginTime + "'";    // 获取周期提示信息和所有一周之内的信息id

            // 获取即时消息
            // "SELECT * FROM zt_remind WHERE sendDept LIKE '%,4,%' OR sendAccount LIKE '%,hujiajia,%'"
            string messageSql = "";
            if (!dept.Equals("")) messageSql = " sendDept LIKE '%," + dept + ",%' OR "; //所属部门
            messageSql = "SELECT * FROM zt_remind WHERE (" + messageSql + " sendAccount LIKE '%," + loginForm.userName + ",%' ) AND `id` IN (" + getIds + ")";
            return messageSql;
        }


        // 获取对应的信息
        public static string getData(string name)
        {
            string sql = getSql(name);
            string data = Tool.Execute(sql);    // 从数据库中查询对应的数据信息
            return data;
        }


        // 获取对应的信息
        public static string getData(Data_AllTab allTabs, string name)
        {
            if (name.Equals("任务")) return Data_AllTab.ToJson(allTabs.task);
            else if (name.Equals("需求")) return Data_AllTab.ToJson(allTabs.story);
            else if (name.Equals("测试")) return Data_AllTab.ToJson(allTabs.test);
            else if (name.Equals("Bug")) return Data_AllTab.ToJson(allTabs.bug);
            else if (name.Equals("日记")) return Data_AllTab.ToJson(allTabs.daily);
            else if (name.Equals("定时信息")) return Data_AllTab.ToJson(allTabs.message);
            else return "";
        }

        public static bool webDataChange = true;

        // 从数据库中，查询对应页面的数据信息
        public static void GetPageDatas()
        {
            if (!isLogined) return;

            // 从新的接口中一次性获取所有表的查询信息
            string dataAll = HttpTool.GetHtml("http://" + loginForm.serverIP + "/zentaodb2.php?account=" + loginForm.userName);
            Data_AllTab allTabs = Data_AllTab.Parse(dataAll);


            foreach (string pageName in pageNames)
            {
                //string data = getData(pageName);            // 获取对应的数据信息
                string data = getData(allTabs, pageName);     // 获取对应的数据信息

                if (webData.Keys.Contains<string>(pageName))// 与已保存的数据比较
                {
                    string value = webData[pageName];
                    if (!value.Equals(data))
                    {
                        webData[pageName] = data;           // 并记录信息的数据信息
                        webDataChange = true;               // 有任务状态变动
                    }
                }
                else webData.Add(pageName, data);           // 保存网页信息到缓存
            }
        }

        # endregion


        bool autoLogined = false;               // 标识当前是否为自动登录
        // 延时自动登录逻辑
        private void timer_loginDelay_Tick(object sender, EventArgs e)
        {
            timer_loginDelay.Enabled = false;
            if (!isLogined && Tool.RegistryCotains(@"Scimence\TaskManager\Set"))    // 未登录，且已保存了账户信息，则自动登录
            {
                autoLogined = true;            
                button_Login_Click(null, null);  // 若未登录，则登录
            }
        }


        # region 新任务提示信息控制逻辑

        // 载入保存的提示信息id
        private static void loadPreMessageIds()
        {
            Task_Ids.loadIdData();          // 载入已提示过的需求信息id
            Demand_Ids.loadIdData();
            Testtask_Ids.loadIdData();
            Bug_Ids.loadIdData();
            Daily_Ids.loadIdData();

            Remind_Ids.loadIdData();        // 提示信息记录载入
            PeriodRemind_Ids.loadIdData();  // 周期性提示信息记录载入
        }

        // 显示当前提示信息
        private static void showCurMessage()
        {
            showCurTaskMessage();
            showCurDemandMessage();
            showCurTesttaskMessage();
            showCurBugMessage();
            showCurDailyMessage();

            showCurRemindMessage();
        }

        // 保存已经提示过的信息id
        public static void saveIdData(TYPE type, string id)
        {
            if (type == TYPE.Task) Task_Ids.saveIdData(id);
            else if (type == TYPE.Demand) Demand_Ids.saveIdData(id);
            else if (type == TYPE.Bug) Bug_Ids.saveIdData(id);
            else if (type == TYPE.Testtask) Testtask_Ids.saveIdData(id);
            else if (type == TYPE.Daily) Daily_Ids.saveIdData(id);
            else if (type == TYPE.Remind)
            {
                Remind_Ids.saveIdData(id);
                savePeriodRemind_IdData(id);// 记录当前提示的周期性提示信息状态
            }
            else if (type == TYPE.Food) FoodRemind.saveTodayFoodInfo();
        }

        # region 定时提示信息，控制逻辑
        private static string RemindName = pageNames[5];        // 名称

        // 用于记录，查询到的提示信息
        private static List<Data_Remind> RemindData = new List<Data_Remind>();
        public static Dictionary<string, Data_Remind> RemindDic = new Dictionary<string, Data_Remind>();
        public static IdInfo<Data_Remind> Remind_Ids = new IdInfo<Data_Remind>(RemindName);

        public static IdInfo<Data_Remind> PeriodRemind_Ids = new IdInfo<Data_Remind>(RemindName + "_按周期提醒");
        public static Dictionary<string, string> Period_IdKeyDic = new Dictionary<string, string>();    // 存储周期提醒信息对应的id和日期key值信息

        // 保存周期性提醒信息记录
        public static void savePeriodRemind_IdData(string remindId)
        {
            if (remindId != null && RemindDic.Keys.Contains(remindId))
            {
                Data_Remind Remind = RemindDic[remindId];
                if (!Remind.period.Equals("once"))
                {
                    string key = Period_IdKeyDic[remindId];
                    PeriodRemind_Ids.saveIdData(key);
                }
            }
        }

        // 获取当前需要提示的需求信息
        private static void showCurRemindMessage()
        {
            // 解析对应页面的提示信息
            string jsonStr = webData[RemindName];
            if (jsonStr.Equals("")) RemindData.Clear();
            else RemindData = Data_Remind.Iteams(jsonStr);

            // 仅提示一次的信息
            List<string> pre_Remind_Ids = Remind_Ids.pre_Ids;
            List<string> cur_Remind_Ids = Remind_Ids.cur_Ids;

            // 按周期循环提示的信息
            List<string> pre_PeriodRemind_Ids = PeriodRemind_Ids.pre_Ids;
            List<string> cur_PeriodRemind_Ids = PeriodRemind_Ids.cur_Ids;

            RemindDic.Clear();

            // 动态获取当前需要提示的信息
            List<Data_Remind> curRemind = new List<Data_Remind>();
            foreach (Data_Remind Remind in RemindData)           // 执行需求信息判定提示逻辑
            {
                RemindDic.Add(Remind.id, Remind);               // 加入字典中存储

                if (Remind.period.Equals("once"))
                {
                    // 对未曾提示的消息进行提示, 正在提示中的消息不再重复提示
                    if (!pre_Remind_Ids.Contains(Remind.id) && !cur_Remind_Ids.Contains(Remind.id))
                    {
                        string timeNow = Tool.TimeNow();            // 获取当前时间
                        string timer = Remind.sendTime;             // 获取定时发送时间

                        int cmp = Tool.Date_cmp(timeNow, timer);    // 若当前时间大于定时时间
                        if (cmp >= 0)
                        {
                            cur_Remind_Ids.Add(Remind.id);
                            curRemind.Add(Remind);
                        }
                    }
                }
                else
                {
                    string timer = Remind.sendTime;             // 获取定时发送时间
                    if (Remind.period.Equals("day")) timer = Tool.toTodayTime(timer);            // 转化为今天对应的提醒时间
                    else if (Remind.period.Equals("week")) 
                        timer = Tool.toThisWeekTime(timer);     // 转化为本周对应的提醒时间
                    else if (Remind.period.Equals("month")) timer = Tool.toThisMonthTime(timer); // 转化为本月对应的提醒时间

                    string newKey = Remind.id + "_" + timer;    // 以信息id和当前提醒的时间作为新的key

                    // 对未曾提示的消息进行提示, 正在提示中的消息不再重复提示
                    if (!pre_PeriodRemind_Ids.Contains(newKey) && !cur_PeriodRemind_Ids.Contains(newKey))
                    {
                        string timeNow = Tool.TimeNow();        // 获取当前时间
                        int cmp = Tool.Date_cmp(timeNow, timer);// 若当前时间大于定时时间
                        if (cmp >= 0)
                        {
                            Period_IdKeyDic.Add(Remind.id, newKey);     // 在缓存字典中保存id和key值信息
                            cur_PeriodRemind_Ids.Add(newKey);           // 记录当前提示的周期信息
                            curRemind.Add(Remind);                      // 添加到当前提示列表
                        }
                    }
                }
            }

            if (isNoticeMode)
            {
                foreach (Data_Remind Remind in curRemind) new NoticeForm(Remind.id, TYPE.Remind, Remind.title).Show();
            }
            else
            {
                if (curRemind.Count == 1) MessageForm.ShowRemind(curRemind[0]);             // 显示提示弹窗
                else if (curRemind.Count > 1) ClockForm.getRemindForm(curRemind).Show();    // 显示多条需求信息界面
            }
        }

        // 获取信息记录,之前已经进行提示的所有信息
        public List<Data_Remind> getRecord()
        {
            List<string> pre_Remind_Ids = Remind_Ids.pre_Ids;

            List<Data_Remind> pre = new List<Data_Remind>();
            foreach (Data_Remind Remind in RemindData)
            {
                if (pre_Remind_Ids.Contains(Remind.id)) pre.Insert(0, Remind);    // 获取已经提示的任务信息
            }

            return pre;
        }

        # endregion 

        # region 指派给我的任务信息，控制逻辑
        private static string TaskName = pageNames[0];        // 名称

        // 用于记录，查询到的需求信息
        public static List<Data_Task> TaskData = new List<Data_Task>();
        public static Dictionary<string, Data_Task> TaskDic = new Dictionary<string, Data_Task>();  
        public static IdInfo<Data_Task> Task_Ids = new IdInfo<Data_Task>(TaskName);

        // 获取当前需要提示的需求信息
        private static void showCurTaskMessage()
        {
            // 解析对应页面的数据信息
            string jsonStr = webData[TaskName];
            if (jsonStr.Equals("")) TaskData.Clear();
            else TaskData = Data_Task.Iteams(jsonStr);

            List<string> pre_Task_Ids = Task_Ids.pre_Ids;
            List<string> cur_Task_Ids = Task_Ids.cur_Ids;

            TaskDic.Clear();

            // 动态获取当前需要提示的信息
            List<Data_Task> curTask = new List<Data_Task>();
            foreach (Data_Task Task in TaskData)           // 执行需求信息判定提示逻辑
            {
                TaskDic.Add(Task.id, Task);      // 加入字典中存储

                // 对未曾提示的消息进行提示, 正在提示中的消息不再重复提示
                if (!pre_Task_Ids.Contains(Task.id) && !cur_Task_Ids.Contains(Task.id))
                {
                    cur_Task_Ids.Add(Task.id);
                    curTask.Add(Task);
                }
            }

            if (isNoticeMode)
            {
                foreach (Data_Task Task in curTask) new NoticeForm(Task.id, TYPE.Task, Task.name, Task.status).Show();
            }
            else
            {
                if (curTask.Count == 1) MessageForm.ShowTask(curTask[0]);             // 显示提示弹窗
                else if (curTask.Count > 1) ClockForm.getTaskForm(curTask).Show();    // 显示多条需求信息界面
            }
        }

        // 对于即将截止的任务给出到期提示信息
        private static void showCurTaskMessage_nearDeadline()
        {
            showCurTaskMessage_nearDeadline(TaskData);
        }

        private static void showCurTaskMessage_nearDeadline(List<Data_Task> TaskData)
        {
            string timeNow = Tool.TimeNow();        // 获取当前时间
            int minute = -1 * loginForm.settings.minute_Before_TaskDeadline;
            int second = loginForm.settings.second_Refresh_Intervate;

            foreach (Data_Task Task in TaskData)
            {
                String state = Tool.toCN(Task.status);
                if (state.Equals("进行中") && !Task.deadline.Equals("0000-00-00 00:00:00"))    // 对进行中的任务判定是否超时
                {
                    try
                    {
                        if (Tool.DateInRegion(timeNow, Task.deadline, minute, second))    // 当前时间在截止时间的前10分钟的20s内
                        {
                            state = "（将到期）";
                            new NoticeForm(Task.id, TYPE.Task, Task.name, state).Show();// 任务将到期时，给出提示信息
                        }
                    }
                    catch (Exception ex) { continue; }
                }
            }
        }

        # endregion 

        # region 指派给我的需求信息，控制逻辑
        private static string DemandName = pageNames[1];        // 名称

        // 用于记录，查询到的需求信息
        public static List<Data_Demand> DemandData = new List<Data_Demand>();
        public static Dictionary<string, Data_Demand> DemandDic = new Dictionary<string, Data_Demand>();  
        public static IdInfo<Data_Demand> Demand_Ids = new IdInfo<Data_Demand>(DemandName);

        // 获取当前需要提示的需求信息
        private static void showCurDemandMessage()
        {
            // 解析对应页面的数据信息
            string jsonStr = webData[DemandName];
            if (jsonStr.Equals("")) DemandData.Clear();
            else DemandData = Data_Demand.Iteams(jsonStr);

            List<string> pre_Demand_Ids = Demand_Ids.pre_Ids;
            List<string> cur_Demand_Ids = Demand_Ids.cur_Ids;

            DemandDic.Clear();

            // 动态获取当前需要提示的信息
            List<Data_Demand> curDemand = new List<Data_Demand>();
            foreach (Data_Demand Demand in DemandData)           // 执行需求信息判定提示逻辑
            {
                DemandDic.Add(Demand.id, Demand);      // 加入字典中存储

                // 对未曾提示的消息进行提示, 正在提示中的消息不再重复提示
                if (!pre_Demand_Ids.Contains(Demand.id) && !cur_Demand_Ids.Contains(Demand.id))
                {
                    cur_Demand_Ids.Add(Demand.id);
                    curDemand.Add(Demand);
                }
            }

            if (isNoticeMode)
            {
                foreach (Data_Demand Demand in curDemand) new NoticeForm(Demand.id, TYPE.Demand, Demand.title, Demand.stage).Show();
            }
            else
            {
                if (curDemand.Count == 1) MessageForm.ShowDemand(curDemand[0]);             // 显示提示弹窗
                else if (curDemand.Count > 1) ClockForm.getDemandForm(curDemand).Show();    // 显示多条需求信息界面
            }
        }
        # endregion 
        
        # region 指派给我的测试信息，控制逻辑
        private static string TesttaskName = pageNames[2];        // 名称

        // 用于记录，查询到的需求信息
        public static List<Data_Testtask> TesttaskData = new List<Data_Testtask>();
        public static Dictionary<string, Data_Testtask> TesttaskDic = new Dictionary<string, Data_Testtask>();  
        public static IdInfo<Data_Testtask> Testtask_Ids = new IdInfo<Data_Testtask>(TesttaskName);

        // 获取当前需要提示的需求信息
        private static void showCurTesttaskMessage()
        {
            // 解析对应页面的数据信息
            string jsonStr = webData[TesttaskName];
            if (jsonStr.Equals("")) TesttaskData.Clear();
            else TesttaskData = Data_Testtask.Iteams(jsonStr);

            List<string> pre_Testtask_Ids = Testtask_Ids.pre_Ids;
            List<string> cur_Testtask_Ids = Testtask_Ids.cur_Ids;

            TesttaskDic.Clear();

            // 动态获取当前需要提示的信息
            List<Data_Testtask> curTesttask = new List<Data_Testtask>();
            foreach (Data_Testtask Testtask in TesttaskData)           // 执行需求信息判定提示逻辑
            {
                TesttaskDic.Add(Testtask.id, Testtask);      // 加入字典中存储

                // 对未曾提示的消息进行提示, 正在提示中的消息不再重复提示
                if (!pre_Testtask_Ids.Contains(Testtask.id) && !cur_Testtask_Ids.Contains(Testtask.id))
                {
                    cur_Testtask_Ids.Add(Testtask.id);
                    curTesttask.Add(Testtask);
                }
            }

            if (isNoticeMode)
            {
                foreach (Data_Testtask Testtask in curTesttask) new NoticeForm(Testtask.id, TYPE.Testtask, Testtask.name, Testtask.status).Show();
            }
            else
            {
                if (curTesttask.Count == 1) MessageForm.ShowTesttask(curTesttask[0]);             // 显示提示弹窗
                else if (curTesttask.Count > 1) ClockForm.getTesttaskForm(curTesttask).Show();    // 显示多条需求信息界面
            }
        }
        # endregion 

        # region 指派给我的Bug信息，控制逻辑
        private static string BugName = pageNames[3];        // 名称

        // 用于记录，查询到的需求信息
        public static List<Data_Bug> BugData = new List<Data_Bug>();
        public static Dictionary<string, Data_Bug> BugDic = new Dictionary<string, Data_Bug>();  
        public static IdInfo<Data_Bug> Bug_Ids = new IdInfo<Data_Bug>(BugName);

        // 获取当前需要提示的需求信息
        private static void showCurBugMessage()
        {
            // 解析对应页面的数据信息
            string jsonStr = webData[BugName];
            if (jsonStr.Equals("")) BugData.Clear();
            else BugData = Data_Bug.Iteams(jsonStr);

            List<string> pre_Bug_Ids = Bug_Ids.pre_Ids;
            List<string> cur_Bug_Ids = Bug_Ids.cur_Ids;

            BugDic.Clear();

            // 动态获取当前需要提示的信息
            List<Data_Bug> curBug = new List<Data_Bug>();
            foreach (Data_Bug Bug in BugData)           // 执行需求信息判定提示逻辑
            {
                BugDic.Add(Bug.id, Bug);      // 加入字典中存储

                // 对未曾提示的消息进行提示, 正在提示中的消息不再重复提示
                if (!pre_Bug_Ids.Contains(Bug.id) && !cur_Bug_Ids.Contains(Bug.id))
                {
                    cur_Bug_Ids.Add(Bug.id);
                    curBug.Add(Bug);
                }
            }

            if (isNoticeMode)
            {
                foreach (Data_Bug Bug in curBug) new NoticeForm(Bug.id, TYPE.Bug, Bug.title, Bug.status).Show();
            }
            else
            {
                if (curBug.Count == 1) MessageForm.ShowBug(curBug[0]);             // 显示提示弹窗
                else if (curBug.Count > 1) ClockForm.getBugForm(curBug).Show();    // 显示多条需求信息界面
            }
        }
        # endregion 

        # region 日记信息，控制逻辑
        private static string DailyName = pageNames[4];        // 名称

        // 用于记录，查询到的需求信息
        public static List<Data_Daily> DailyData = new List<Data_Daily>();
        public static Dictionary<string, Data_Daily> DailyDic = new Dictionary<string, Data_Daily>();   
        public static IdInfo<Data_Daily> Daily_Ids = new IdInfo<Data_Daily>(DailyName);

        // 获取当前需要提示的需求信息
        private static void showCurDailyMessage()
        {
            // 解析对应页面的数据信息
            string jsonStr = webData[DailyName];
            if (jsonStr.Equals("")) DailyData.Clear();
            else DailyData = Data_Daily.Iteams(jsonStr);

            List<string> pre_Daily_Ids = Daily_Ids.pre_Ids;
            List<string> cur_Daily_Ids = Daily_Ids.cur_Ids;

            DailyDic.Clear();

            // 动态获取当前需要提示的信息
            List<Data_Daily> curDaily = new List<Data_Daily>();
            foreach (Data_Daily Daily in DailyData)           // 执行需求信息判定提示逻辑
            {
                DailyDic.Add(Daily.id, Daily);      // 加入字典中存储

                // 对未曾提示的消息进行提示, 正在提示中的消息不再重复提示
                if (!pre_Daily_Ids.Contains(Daily.id) && !cur_Daily_Ids.Contains(Daily.id))
                {
                    cur_Daily_Ids.Add(Daily.id);
                    curDaily.Add(Daily);
                }
            }

            //if (isNoticeMode)
            //{
            //    foreach (Data_Daily Daily in curDaily) new NoticeForm(Daily.id, TYPE.Daily, Daily.work, Daily.dstatus).Show();
            //}
            //else
            //{
            //    if (curDaily.Count == 1) MessageForm.ShowDaily(curDaily[0]);             // 显示提示弹窗
            //    else if (curDaily.Count > 1) ClockForm.getDailyForm(curDaily).Show();    // 显示多条需求信息界面
            //}
        }
        # endregion 



        # region 新任务提示信息id，的保存与载入

        public class IdInfo<T>
        {
            public string name = "XXX"; // 保存信息类型名

            public List<string> pre_Ids = new List<string>();     // 已经进行提示的需求id
            public List<string> cur_Ids = new List<string>();     // 正在进行提示的需求id


            // 获取指派给我的需求信息 name="需求"
            public IdInfo(string name)
            {
                this.name = name;
            }

            // 保存已经提示的信息id
            public void saveIdData(string id)
            {
                if (!pre_Ids.Contains(id))
                {
                    cur_Ids.Remove(id);                   // 从正在提示列表中移除
                    pre_Ids.Add(id);                      // 添加id到已经提示列表
                    string data = Tool.toString(pre_Ids); // 转化已提示消息的id数据为字符串
                    SaveTxt(data, userName + "_" + name);    // 存储字符串至文件中
                }
            }

            // 从缓存文件中读取，上次已经提示过的信息id
            public void loadIdData()
            {
                string data = getLocalData(userName + "_" + name);          // 从本地缓存文件中读取数据
                if (!data.Equals("")) pre_Ids = Tool.toList(data);   // 转化List
            }
        }

        # endregion


        

        #region 文件读取与保存

        // 从默认路径中获取任务状态缓存数据
        public static string getLocalData(String name)
        {
            String filePath = CurDir() + name + ".txt";
            return fileToString(filePath);
        }

        /// <summary>
        /// 获取文件中的数据串
        /// </summary>
        public static string fileToString(String filePath)
        {
            string str = "";

            //获取文件内容
            if (System.IO.File.Exists(filePath))
            {
                System.IO.StreamReader file1 = new System.IO.StreamReader(filePath);//读取文件中的数据
                str = file1.ReadToEnd();                                            //读取文件中的全部数据

                file1.Close();
                file1.Dispose();
            }
            return str;
        }

        // 获取当前软件的存储路径，若不存在则创建
        public static string CurDir()
        {
            string CurDir = System.AppDomain.CurrentDomain.BaseDirectory + "TaskManager_data\\";        //设置当前目录
            if (!System.IO.Directory.Exists(CurDir)) System.IO.Directory.CreateDirectory(CurDir);   //该路径不存在时，在当前文件目录下创建文件夹"导出.."

            return CurDir;    //设置当前目录
        }

        /// <summary>
        /// 保存数据data到文件处理过程，返回值为保存的文件名
        /// </summary>
        public static String SaveTxt(String data, String name)
        {
            //不存在该文件时先创建
            String filePath = CurDir() + name +  ".txt";
            SaveProcess(data, filePath);
            return filePath;
        }

        /// <summary>
        /// 保存数据data到文件处理过程，返回值为保存的文件名
        /// </summary>
        public static String SaveProcess(String data, String filePath)
        {
            if (filePath == null || filePath.Equals("")) return "";

            // 创建父目录
            String ParentDir = filePath.Substring(0, filePath.LastIndexOf(@"\"));
            if (!Directory.Exists(ParentDir)) Directory.CreateDirectory(ParentDir);

            //不存在该文件时先创建
            System.IO.StreamWriter file1 = new System.IO.StreamWriter(filePath, false);     //文件已覆盖方式添加内容

            file1.Write(data);                                                              //保存数据到文件

            file1.Close();                                                                  //关闭文件
            file1.Dispose();                                                                //释放对象

            return filePath;
        }

        #endregion


        # region 设置信息的载入与保存
        public static SettingData settings = new SettingData();

        //载入设置信息
        public static void loadSetttingData()
        {
            string str = getLocalData("设置");
            if (!str.Equals("")) settings = SettingData.Parse(str);
            if (settings.second_Refresh_Intervate < 90) settings.second_Refresh_Intervate = 90; // 修改最小刷新时间为90秒

            // 若配置信息变动，则保存当前设置信息
            string Json = settings.ToJson();
            if(!Json.Equals(str)) SaveTxt(settings.ToJson(), "设置");
        }

        // 保存设置信息到文件
        public static void saveSetttingData()
        {
            SaveTxt(settings.ToJson(), "设置");
        }
        #endregion


        private void 显示ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            MouseEventArgs e1 = new MouseEventArgs(MouseButtons.Left, 1, 0, 0, 0);
            OpenManagerForm(null, e1);
        }

        # endregion

        private void 隐藏ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            CloseManagerForm(null, null);
        }

        private void comboBox_server_SelectedIndexChanged(object sender, EventArgs e)
        {
            label3.Visible = comboBox_server.Text.Equals("task.joymeng.com");
        }

        private SettingsForm_TaskManager settings_form;
        private void 设置ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (settings_form != null)settings_form.Close();

            settings_form = new SettingsForm_TaskManager();
            settings_form.Show();
        }

        // 打开禅道网页端
        private void linkLabel_openLogain_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            serverIP = comboBox_server.Text.Trim();             // 获取服务器名
            HttpTool.openUrl("http://" + serverIP + "/user-login.html", false);
        }
    
    }
}
